package com.csun.cmny.provider.service.impl;

import com.csun.cmny.base.constant.GlobalConstant;
import com.csun.cmny.base.dto.LoginAuthDto;
import com.csun.cmny.base.enums.ErrorCodeEnum;
import com.csun.cmny.core.support.BaseService;
import com.csun.cmny.provider.dao.UacRoleMapper;
import com.csun.cmny.provider.dao.UacRoleMenuMapper;
import com.csun.cmny.provider.model.constant.RoleConstant;
import com.csun.cmny.provider.model.domain.*;
import com.csun.cmny.provider.model.dto.action.ActionMainQueryDto;
import com.csun.cmny.provider.model.dto.menu.MenuQueryDto;
import com.csun.cmny.provider.model.dto.role.*;
import com.csun.cmny.provider.model.enums.UacRoleCodeEnum;
import com.csun.cmny.provider.model.enums.UacRoleStatusEnum;
import com.csun.cmny.provider.model.exceptions.UacBizException;
import com.csun.cmny.provider.model.vo.BindAuthVo;
import com.csun.cmny.provider.model.vo.MenuVo;
import com.csun.cmny.provider.model.vo.RoleVo;
import com.csun.cmny.provider.model.vo.RpcRoleVo;
import com.csun.cmny.provider.model.vo.role.MenuCountVo;
import com.csun.cmny.provider.resolver.CmnyMessageSource;
import com.csun.cmny.provider.service.*;
import com.csun.cmny.provider.utils.TreeUtil;
import com.csun.cmny.util.PublicUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.common.base.Joiner;
import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;


/**
 * The class Uac role service.
 *
 * @author paascloud.net@gmail.com
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class UacRoleServiceImpl extends BaseService<UacRole> implements UacRoleService {

	@Resource
	private UacRoleMapper uacRoleMapper;
	@Resource
	private UacRoleUserService uacRoleUserService;
	@Resource
	private UacRoleMenuMapper uacRoleMenuMapper;
	@Resource
	private UacUserService uacUserService;
	@Resource
	private UacRoleMenuService uacRoleMenuService;
	@Resource
	private UacMenuService uacMenuService;
	@Resource
	private UacActionService uacActionService;
	@Resource
	private UacRoleActionService uacRoleActionService;
	@Resource
	private CmnyMessageSource cmnyMessageSource;
	@Resource
	private UacGroupRoleService uacGroupRoleService;
	@Resource
	private UacGroupRoleActionService uacGroupRoleActionService;

	@Override
	@Transactional(readOnly = true, rollbackFor = Exception.class)
	public UacRole findByRoleCode(String roleCode) {
		return uacRoleMapper.findByRoleCode(roleCode);
	}

	@Override
	@Transactional(readOnly = true, rollbackFor = Exception.class)
	public List<RoleVo> queryRoleListWithPage(UacRole role) {
		return uacRoleMapper.queryRoleListWithPage(role);
	}

	@Override
	public int deleteRoleById(Long roleId) {

		if (null == roleId) {
			throw new IllegalArgumentException(ErrorCodeEnum.UAC10012001.msg());
		}

		// 判断角色是否存在
		UacRole uacRole = uacRoleMapper.selectByPrimaryKey(roleId);
		if (PublicUtil.isEmpty(uacRole)) {
			throw new UacBizException(ErrorCodeEnum.UAC10012009);
		}

		// 超级管理员不能删除
		if (Objects.equals(roleId, GlobalConstant.Sys.SUPER_MANAGER_ROLE_ID)) {
			throw new UacBizException(ErrorCodeEnum.UAC10012003);
		}

		// 系统指定的角色不能进行删除
		String roleName = UacRoleCodeEnum.getName(uacRole.getRoleCode());
		if (PublicUtil.isNotEmpty(roleName)) {
			throw new UacBizException(ErrorCodeEnum.UAC10012003);
		}

		// 判断机构-角色是否初始化
		UacGroupRole uacGroupRole = new UacGroupRole();
		uacGroupRole.setRoleId(roleId);
		int count = uacGroupRoleService.selectCount(uacGroupRole);
		if (count > 0) {
			throw new UacBizException(ErrorCodeEnum.UAC10012013);
		}

		// 绑定了用户不能删除
		UacRoleUser uacRoleUser = new UacRoleUser();
		uacRoleUser.setRoleId(roleId);
		count = uacRoleUserService.selectCount(uacRoleUser);
		if (count > 0) {
			throw new UacBizException(ErrorCodeEnum.UAC10012014);
		}

		// 绑定了菜单不能删除
		UacRoleMenu uacRoleMenu = new UacRoleMenu();
		uacRoleMenu.setRoleId(roleId);
		count = uacRoleMenuService.selectCount(uacRoleMenu);
		if (count > 0) {
			throw new UacBizException(ErrorCodeEnum.UAC10012015);
		}

		// 绑定了功能不能删除
		UacRoleAction uacRoleAction = new UacRoleAction();
		uacRoleAction.setRoleId(roleId);
		count = uacRoleActionService.selectCount(uacRoleAction);
		if (count > 0) {
			throw new UacBizException(ErrorCodeEnum.UAC10012016);
		}

//		List<UacRoleUser> uruList = uacRoleUserService.listByRoleId(roleId);
//
//		if (!uruList.isEmpty()) {
//			uacRoleUserService.deleteByRoleId(roleId);
//		}

		// uacRoleActionService.deleteByRoleId(roleId);
		// uacRoleMenuService.deleteByRoleId(roleId);
		return uacRoleMapper.deleteByPrimaryKey(roleId);
	}

	@Override
	public int saveRole(UacRole role, LoginAuthDto loginAuthDto) {

		// 校验角色编码
		Preconditions.checkArgument(role.getRoleCode() != null,
				cmnyMessageSource.getMessage("role.code.null", null));

		CheckRoleCodeDto checkRoleCodeDto = new CheckRoleCodeDto();
		checkRoleCodeDto.setRoleCode(role.getRoleCode());
		if (!checkUacRoleCode(checkRoleCodeDto)) {
			throw new UacBizException(ErrorCodeEnum.UAC10012010);
		}

		// 校验角色名称不能为空
		Preconditions.checkArgument(PublicUtil.isNotEmpty(role.getRoleName()),
				cmnyMessageSource.getMessage("role.name.null", null));

		// 校验角色编码是否唯一
		CheckRoleNameDto checkRoleNameDto = new CheckRoleNameDto();
		checkRoleNameDto.setRoleName(role.getRoleName());
		if (!checkUacRoleName(checkRoleNameDto)) {
			throw new UacBizException(ErrorCodeEnum.UAC10012012);
		}

		role.setStatus(UacRoleStatusEnum.ENABLE.getType());
		role.setUpdateInfo(loginAuthDto);

		return uacRoleMapper.insertSelective(role);
	}

	@Override
	@Transactional(readOnly = true, rollbackFor = Exception.class)
	public List<Long> getAuthTreeNoCheckMenu(Long roleId) {
		//查询某个角色下一级菜单下的二级菜单个数, 去掉二级菜单个数为0的一级菜单选中状态
		List<MenuCountVo> menuCountVos = uacRoleMenuMapper.countChildMenuNum(roleId);
		List<Long> noCheckedMenu = Lists.newArrayList();
		for (MenuCountVo vo : menuCountVos) {
			noCheckedMenu.add(vo.getId());
		}

		return noCheckedMenu;
	}

	@Override
	public void bindAction(RoleBindActionDto grantAuthRole) {
		Long roleId = grantAuthRole.getRoleId();
		Set<Long> actionIdList = grantAuthRole.getActionIdList();

		if (roleId == null) {
			throw new UacBizException(ErrorCodeEnum.UAC10012001);
		}

		if (Objects.equals(roleId, GlobalConstant.Sys.SUPER_MANAGER_ROLE_ID)) {
			logger.error("越权操作, 超级管理员用户不允许操作");
			throw new UacBizException(ErrorCodeEnum.UAC10011023);
		}

		UacRole uacRole = uacRoleMapper.selectByPrimaryKey(roleId);

		if (uacRole == null) {
			logger.error("找不到角色信息. roleId={}", roleId);
			throw new UacBizException(ErrorCodeEnum.UAC10012005, roleId);
		}

		// TODO 校验参数的合法性(这里不写了 累得慌 也就是校验菜单和权限是否存在)
		List<UacRoleAction> uacRoleActionList = uacRoleActionService.listByRoleId(roleId);

		if (PublicUtil.isNotEmpty(uacRoleActionList)) {
			uacRoleActionService.deleteByRoleId(roleId);
		}

		if (PublicUtil.isEmpty(actionIdList)) {
			logger.error("传入按钮权限Id为空, 取消所有按钮权限");
		} else {
			// 绑定权限
			uacRoleActionService.insert(roleId, actionIdList);
		}
	}

	@Override
	@Transactional(readOnly = true, rollbackFor = Exception.class)
	public UacRole getRoleById(Long roleId) {
		return uacRoleMapper.selectByPrimaryKey(roleId);
	}

	@Override
	@Transactional(readOnly = true, rollbackFor = Exception.class)
	public RoleBindUserDto getRoleBindUserDto(Long roleId, Long currentUserId) {
		RoleBindUserDto roleBindUserDto = new RoleBindUserDto();
		Set<Long> alreadyBindUserIdSet = Sets.newHashSet();
		UacRole uacRole = uacRoleMapper.selectByPrimaryKey(roleId);
		if (PublicUtil.isEmpty(uacRole)) {
			logger.error("找不到roleId={}, 的角色", roleId);
			throw new UacBizException(ErrorCodeEnum.UAC10012005, roleId);
		}

		// 查询所有用户包括已禁用的用户
		List<BindUserDto> bindUserDtoList = uacRoleMapper.selectAllNeedBindUser(GlobalConstant.Sys.SUPER_MANAGER_ROLE_ID, currentUserId);
		// 该角色已经绑定的用户
		List<UacRoleUser> setAlreadyBindUserSet = uacRoleUserService.listByRoleId(roleId);
		Set<BindUserDto> allUserSet = new HashSet<>(bindUserDtoList);

		for (UacRoleUser uacRoleUser : setAlreadyBindUserSet) {
			alreadyBindUserIdSet.add(uacRoleUser.getUserId());
		}

		roleBindUserDto.setAllUserSet(allUserSet);
		roleBindUserDto.setAlreadyBindUserIdSet(alreadyBindUserIdSet);

		return roleBindUserDto;
	}

	@Override
	public void bindUser4Role(RoleBindUserReqDto roleBindUserReqDto, LoginAuthDto authResDto) {

		if (roleBindUserReqDto == null) {
			logger.error("参数不能为空");
			throw new IllegalArgumentException("参数不能为空");
		}

		Long roleId = roleBindUserReqDto.getRoleId();
		Long loginUserId = authResDto.getUserId();
		List<Long> userIdList = roleBindUserReqDto.getUserIdList();

		if (null == roleId) {
			throw new IllegalArgumentException(ErrorCodeEnum.UAC10012001.msg());
		}

		UacRole role = this.getRoleById(roleId);

		if (role == null) {
			logger.error("找不到角色信息 roleId={}", roleId);
			throw new UacBizException(ErrorCodeEnum.UAC10012005, roleId);
		}

//		if (PublicUtil.isNotEmpty(userIdList) && userIdList.contains(loginUserId)) {
//			logger.error("不能操作当前登录用户 userId={}", loginUserId);
//			throw new UacBizException(ErrorCodeEnum.UAC10011023);
//		}

		// 查询超级管理员用户Id集合
//		List<Long> superUserList = uacRoleUserService.listSuperUser(GlobalConstant.Sys.SUPER_MANAGER_ROLE_ID);
//		List<Long> unionList = Collections3.intersection(userIdList, superUserList);
//		if (PublicUtil.isNotEmpty(userIdList) && PublicUtil.isNotEmpty(unionList)) {
//			logger.error("不能操作超级管理员用户 超级用户={}", unionList);
//			throw new UacBizException(ErrorCodeEnum.UAC10011023);
//		}

		// 1. 先取消对该角色的用户绑定(不包含超级管理员用户)
		List<UacRoleUser> userRoles = uacRoleUserService.listByRoleId(roleId);

		if (PublicUtil.isNotEmpty(userRoles)) {
			uacRoleUserService.deleteExcludeSuperMng(roleId, GlobalConstant.Sys.SUPER_MANAGER_ROLE_ID);
		}

		// 批量删除角色用户
//		uacRoleUserService.deleteByRoleId(roleId);

		if (PublicUtil.isEmpty(userIdList)) {
			// 取消该角色的所有用户的绑定
			logger.info("取消绑定所有非超级管理员用户成功");
			return;
		}

		// 绑定所选用户
//		for (Long userId : userIdList) {
//			UacUser uacUser = uacUserService.queryByUserId(userId);
//			if (PublicUtil.isEmpty(uacUser)) {
//				logger.error("找不到绑定的用户 userId={}", userId);
//				throw new UacBizException(ErrorCodeEnum.UAC10011024, userId);
//			}
//			uacRoleUserService.saveRoleUser(userId, roleId);
//		}

		Integer result = uacRoleUserService.batchSaveRoleAndUserList(roleId, userIdList);

	}

	@Override
	@Transactional(readOnly = true, rollbackFor = Exception.class)
	public List<UacRole> findAllRoleInfoByUserId(Long userId) {
		return uacRoleMapper.selectAllRoleInfoByUserId(userId);
	}

	@Override
	@Transactional(readOnly = true, rollbackFor = Exception.class)
	public BindAuthVo getActionTreeByRoleId(Long roleId) {
		BindAuthVo bindAuthVo = new BindAuthVo();
		if (roleId == null) {
			throw new UacBizException(ErrorCodeEnum.UAC10012001);
		}

		UacRole roleById = this.getRoleById(roleId);
		if (roleById == null) {
			logger.error("找不到角色信息 roleId={}", roleId);
			throw new UacBizException(ErrorCodeEnum.UAC10012005, roleId);
		}

		// 校验角色Id是否为空
//		Preconditions.checkArgument(menuQueryDto.getRoleId() != null,
//				cmnyMessageSource.getMessage("role.id.null", null));

		List<UacMenu> uacMenus;
		List<UacAction> uacActions;

		// 获取所有绑定的菜单和按钮权限Id集合
		List<Long> checkedAuthList = uacActionService.getCheckedMenuList(roleId);
		MenuQueryDto menuQueryDto = new MenuQueryDto();
		menuQueryDto.setPageSize(65535);
		if (PublicUtil.isEmpty(checkedAuthList)) {
			uacMenus = uacMenuService.queryMenuAndSubMenuListWithPage(menuQueryDto);
		} else {
			menuQueryDto.setMenuIds(StringUtils.join(checkedAuthList, ","));
			// 查询
			uacMenus = uacMenuService.queryRoleMenuListWithPage(menuQueryDto);
		}

		// List<UacMenu> uacMenus = uacMenuService.listMenuListByRoleId(roleId);

//		if (PublicUtil.isEmpty(uacMenus)) {
//			throw new UacBizException(ErrorCodeEnum.UAC10013009);
//		}

		ActionMainQueryDto actionMainQueryDto = new ActionMainQueryDto();
		actionMainQueryDto.setPageSize(65535);
		checkedAuthList = uacActionService.getCheckedActionList(roleId);
		if (PublicUtil.isEmpty(checkedAuthList)) {
			uacActions = uacActionService.queryActionList(actionMainQueryDto);
		} else {
			actionMainQueryDto.setActionIds(StringUtils.join(checkedAuthList, ","));
			uacActions = uacActionService.queryRoleActionList(actionMainQueryDto);
		}

		// 查询所有的权限信息
		// List<UacAction> uacActions = uacActionService.listActionList(uacMenus);

//        if (PublicUtil.isEmpty(uacActions)) {
//            uacActions = Lists.newArrayList();
//        }

        // 合并菜单和按钮权限 递归生成树结构
		List<MenuVo> menuVoList = uacMenuService.getAuthList(uacMenus, uacActions);

		List<MenuVo> tree = TreeUtil.getChildMenuVos(menuVoList, 0L);

		// 获取所有绑定的菜单和按钮权限Id集合
		// List<Long> checkedAuthList = uacActionService.getCheckedActionList(roleId);

		bindAuthVo.setAuthTree(tree);
		bindAuthVo.setCheckedAuthList(checkedAuthList);

		return bindAuthVo;
	}

	@Override
	public void batchDeleteByIdList(List<Long> roleIdList) {
		logger.info("批量删除角色. idList={}", roleIdList);
		Preconditions.checkArgument(PublicUtil.isNotEmpty(roleIdList), "删除角色ID不存在");

		List<UacRoleUser> uruList = uacRoleUserService.listByRoleIdList(roleIdList);
		if (!uruList.isEmpty()) {
			uacRoleUserService.deleteByRoleIdList(roleIdList);
		}

		uacRoleMenuService.deleteByRoleIdList(roleIdList);
		uacRoleActionService.deleteByRoleIdList(roleIdList);

		int result = uacRoleMapper.batchDeleteByIdList(roleIdList);
		if (result < roleIdList.size()) {
			throw new UacBizException(ErrorCodeEnum.UAC10012006, Joiner.on(GlobalConstant.Symbol.COMMA).join(roleIdList));
		}
	}

	@Override
	@Transactional(readOnly = true, rollbackFor = Exception.class)
	public List<MenuVo> getOwnAuthTree(Long userId) {
		if (userId == null) {
			throw new UacBizException(ErrorCodeEnum.UAC10011001);
		}

		return uacMenuService.getMenuVoList(userId, GlobalConstant.Sys.OPER_APPLICATION_ID);
	}

	@Override
	public void bindMenu(RoleBindMenuDto roleBindMenuDto) {

		Long roleId = roleBindMenuDto.getRoleId();
		Set<Long> menuIdList = roleBindMenuDto.getMenuIdList();

		if (roleId == null) {
			throw new UacBizException(ErrorCodeEnum.UAC10012001);
		}

		if (Objects.equals(roleId, GlobalConstant.Sys.SUPER_MANAGER_ROLE_ID)) {
			logger.error("越权操作, 超级管理员用户不允许操作");
			throw new UacBizException(ErrorCodeEnum.UAC10011023);
		}

		UacRole uacRole = uacRoleMapper.selectByPrimaryKey(roleId);

		if (uacRole == null) {
			logger.error("找不到角色信息. roleId={}", roleId);
			throw new UacBizException(ErrorCodeEnum.UAC10012005, roleId);
		}

		// TODO 校验参数的合法性(这里不写了 累得慌 也就是校验菜单和权限是否存在)
		List<UacRoleMenu> uacRoleMenuList = uacRoleMenuService.listByRoleId(roleId);

		if (PublicUtil.isNotEmpty(uacRoleMenuList)) {
			uacRoleMenuService.deleteByRoleId(roleId);
		}

		// menuSet actionIdList 如果为空则 取消该角色所有权限
		if (PublicUtil.isEmpty(menuIdList)) {
			logger.error("传入菜单权限Id为空, 取消菜单权限");
		} else {
			// 绑定菜单
			uacRoleMenuService.insert(roleId, menuIdList);

		}
	}

	@Override
	@Transactional(readOnly = true, rollbackFor = Exception.class)
	public BindAuthVo getMenuTreeByRoleId(Long roleId) {
		BindAuthVo bindAuthVo = new BindAuthVo();
		Preconditions.checkArgument(roleId != null, ErrorCodeEnum.UAC10012001.msg());

		UacRole roleById = this.getRoleById(roleId);
		if (roleById == null) {
			logger.error("找不到角色信息 roleId={}", roleId);
			throw new UacBizException(ErrorCodeEnum.UAC10012005, roleId);
		}

		// 获取所有绑定的菜单和按钮权限Id集合
		List<Long> checkedAuthList = uacActionService.getCheckedMenuList(roleId);

		return uacMenuService.getMenuTreeByMenuIdList(checkedAuthList);
	}

	/**
	 * query role list by user id
	 *
	 * @param userId user id
	 * @return the list
	 */
	@Override
	public List<RpcRoleVo> queryRoleListByUserId(Long userId) {

		return uacRoleMapper.queryRoleListByUserId(userId);
	}

	/**
	 * 校验角色编码是否已经存在
	 *
	 * @param checkRoleCodeDto the check role code dto
	 * @return the boolean true-不存在, false-存在
	 */
	@Override
	public boolean checkUacRoleCode(CheckRoleCodeDto checkRoleCodeDto) {
		Long id = checkRoleCodeDto.getRoleId();
		String roleCode = checkRoleCodeDto.getRoleCode();

		Example example = new Example(UacRole.class);
		Example.Criteria criteria = example.createCriteria();

		if (id != null) {
			criteria.andNotEqualTo("id", id);
		}
		criteria.andEqualTo("roleCode", roleCode);

		int result = selectCountByExample(example);

		return result < 1;
	}

	/**
	 * 校验角色名称是否已经存在
	 *
	 * @param checkRoleNameDto	the check role name dto
	 *
	 * @return	the boolean true-不存在 false-存在
	 */
	@Override
	public boolean checkUacRoleName(CheckRoleNameDto checkRoleNameDto) {

		Long id = checkRoleNameDto.getRoleId();
		String roleName = checkRoleNameDto.getRoleName();

		Example example = new Example(UacRole.class);
		Example.Criteria criteria = example.createCriteria();

		if (id != null) {
			criteria.andNotEqualTo("id", id);
		}
		criteria.andEqualTo("roleName", roleName);

		int result = selectCountByExample(example);

		return result < 1;
	}

	/**
	 * 修改角色信息
	 *
	 * @param uacRole the uac role
	 * @return the int
	 */
	@Override
	public Integer editUacRole(UacRole uacRole, LoginAuthDto loginAuthDto) {

		// 校验角色是否存在
		UacRole uacRoleQuery = uacRoleMapper.selectByPrimaryKey(uacRole.getId());
		if (PublicUtil.isEmpty(uacRoleQuery)) {
			throw new UacBizException(ErrorCodeEnum.UAC10012009);
		}

		// 校验角色编码是否唯一
		if (PublicUtil.isNotEmpty(uacRole.getRoleName())) {
			CheckRoleNameDto checkRoleNameDto = new CheckRoleNameDto();
			checkRoleNameDto.setRoleId(uacRole.getId());
			checkRoleNameDto.setRoleName(uacRole.getRoleName());
			if (!checkUacRoleName(checkRoleNameDto)) {
				throw new UacBizException(ErrorCodeEnum.UAC10012012);
			}
		}

		// 校验角色编码是否唯一
		if (PublicUtil.isNotEmpty(uacRole.getRoleCode())) {
			// 判断是否相同
			if (!uacRole.getRoleCode().equals(uacRoleQuery.getRoleCode())) {
				// 校验修改后的编码是否重复
				CheckRoleCodeDto checkRoleCodeDto = new CheckRoleCodeDto();
				checkRoleCodeDto.setRoleId(uacRole.getId());
				checkRoleCodeDto.setRoleCode(uacRole.getRoleCode());
				if (!checkUacRoleCode(checkRoleCodeDto)) {
					throw new UacBizException(ErrorCodeEnum.UAC10012010);
				}

				// 校验角色是否正在使用
				UacRoleUser uacRoleUser = new UacRoleUser();
				uacRoleUser.setRoleId(uacRole.getId());
				int count = uacRoleUserService.selectCount(uacRoleUser);
				if (count > 1) {
					throw new UacBizException(ErrorCodeEnum.UAC10012011);
				}
			}
		}

		uacRole.setUpdateInfo(loginAuthDto);

		return uacRoleMapper.updateByPrimaryKeySelective(uacRole);
	}

	/**
	 * 查询角色菜单列表
	 *
	 * @param menuQueryDto role menu query dto
	 *
	 * @return the page info.
	 */
	@Override
	public PageInfo queryRoleMenuListWithPage(MenuQueryDto menuQueryDto) {

		// 校验角色Id是否为空
        Preconditions.checkArgument(menuQueryDto.getRoleId() != null,
                cmnyMessageSource.getMessage("role.id.null", null));

        List<UacMenu> uacMenuList = Lists.newArrayList();
        // 获取所有绑定的菜单和按钮权限Id集合
        List<Long> checkedAuthList = uacActionService.getCheckedMenuList(menuQueryDto.getRoleId());

        // 分页
        PageHelper.startPage(menuQueryDto.getPageNum(), menuQueryDto.getPageSize());
        if (PublicUtil.isEmpty(checkedAuthList)) {
            uacMenuList = uacMenuService.queryMenuAndSubMenuListWithPage(menuQueryDto);
        } else {
            menuQueryDto.setMenuIds(StringUtils.join(checkedAuthList, ","));
            // 查询
            uacMenuList= uacMenuService.queryRoleMenuListWithPage(menuQueryDto);
        }

		return new PageInfo<>(uacMenuList);
	}

	/**
	 * 分配角色菜单
	 *
	 * @param roleAssignMenuDto
	 * @return
	 */
	@Override
	public Integer assignRoleMenu(RoleAssignMenuDto roleAssignMenuDto) {

		// 校验角色Id不为空
		Preconditions.checkArgument(roleAssignMenuDto.getRoleId() != null,
				cmnyMessageSource.getMessage("role.id.null", null));

		// 校验分配菜单列表不为空
		Preconditions.checkArgument(PublicUtil.isNotEmpty(roleAssignMenuDto.getAssignMenuDtoList()),
				cmnyMessageSource.getMessage("menu.list.null", null));

		// TODO 校验角色Id是否存在

		// TODO 校验菜单Id是否存在

		List<Long> checkMenuList = Lists.newArrayList();
		List<Long> deleteMenuList = Lists.newArrayList();
		// 将分配的菜单按照'选中','移除'分为两组
		for (AssignMenuDto amd : roleAssignMenuDto.getAssignMenuDtoList()) {
			switch (amd.getCheck()) {
				case RoleConstant.CHECK_STATUS_SLT :
					checkMenuList.add(amd.getMenuId());
					break;
				case RoleConstant.CHECK_STATUS_RID :
					deleteMenuList.add(amd.getMenuId());
					break;
			}
		}

        int result = 0;
		// 批量添加角色菜单
        if (PublicUtil.isNotEmpty(checkMenuList)) {
            result += uacRoleMenuService.batchSave(roleAssignMenuDto.getRoleId(), checkMenuList);
        }

		// 批量删除角色菜单
        if (PublicUtil.isNotEmpty(deleteMenuList)) {
            result += uacRoleMenuService.batchDelete(roleAssignMenuDto.getRoleId(), deleteMenuList);
        }

		return result;
	}

    /**
     * 分配角色菜单
     *
     * @param roleAssignActionDto 分配角色功能对象
     *
     * @return 影响的行数
     */
    @Override
    public Integer assignRoleAction(RoleAssignActionDto roleAssignActionDto) {

        // 校验角色Id不为空
        Preconditions.checkArgument(roleAssignActionDto.getRoleId() != null,
                cmnyMessageSource.getMessage("role.id.null", null));

        // 校验分配菜单列表不为空
        Preconditions.checkArgument(PublicUtil.isNotEmpty(roleAssignActionDto.getAssignActionDtoList()),
                cmnyMessageSource.getMessage("action.list.null", null));

        // TODO 校验角色Id是否存在

        // TODO 校验菜单Id是否存在

        List<Long> checkActionList = Lists.newArrayList();
        List<Long> deleteActionList = Lists.newArrayList();
        // 将分配的菜单按照'选中','移除'分为两组
        for (AssignActionDto aad : roleAssignActionDto.getAssignActionDtoList()) {
            switch (aad.getCheck()) {
                case RoleConstant.CHECK_STATUS_SLT :
                    checkActionList.add(aad.getActionId());
                    break;
                case RoleConstant.CHECK_STATUS_RID :
                    deleteActionList.add(aad.getActionId());
                    break;
            }
        }

        int result = 0;
        // 批量添加角色菜单
        if (PublicUtil.isNotEmpty(checkActionList)) {
            result += uacRoleActionService.batchSave(roleAssignActionDto.getRoleId(), checkActionList);
        }

        // 批量删除角色菜单
        if (PublicUtil.isNotEmpty(deleteActionList)) {
            result += uacRoleActionService.batchDelete(roleAssignActionDto.getRoleId(), deleteActionList);
        }

        return result;
    }

    /**
     * 查询角色功能列表
     *
     * @param actionMainQueryDto the action main query dto
     * @return the page info
     */
    @Override
    public PageInfo queryRoleActionListWithPage(ActionMainQueryDto actionMainQueryDto) {

        Long roleId = actionMainQueryDto.getRoleId();
        // 校验角色Id不为空
        Preconditions.checkArgument(actionMainQueryDto.getRoleId() != null,
                cmnyMessageSource.getMessage("role.id.null", null));

        UacRole roleById = this.getRoleById(roleId);
        if (roleById == null) {
            logger.error("找不到角色信息 roleId={}", roleId);
            throw new UacBizException(ErrorCodeEnum.UAC10012005, roleId);
        }

        // 查询指定菜单下所有的子菜单
        if (PublicUtil.isNotEmpty(actionMainQueryDto.getMenuId())) {
            List<Long> menuIdList = uacMenuService.queryMenuAndSubMenuIds(actionMainQueryDto.getMenuId());
            actionMainQueryDto.setMenuId(null);
            actionMainQueryDto.setMenuIdList(menuIdList);
        }

        List<UacAction> uacActionList = Lists.newArrayList();
        // 获取所有绑定的按钮权限Id集合
        List<Long> checkedAuthList = uacActionService.getCheckedActionList(roleId);

        // 分页
        PageHelper.startPage(actionMainQueryDto.getPageNum(), actionMainQueryDto.getPageSize());
        if (PublicUtil.isEmpty(checkedAuthList)) {
            uacActionList = uacActionService.queryActionList(actionMainQueryDto);
        } else {
            actionMainQueryDto.setActionIds(StringUtils.join(checkedAuthList, ","));
            // 查询
            uacActionList= uacActionService.queryRoleActionList(actionMainQueryDto);
        }

        return new PageInfo<>(uacActionList);
    }

    /**
     * 根据功能Id查询角色列表
     *
     * @param roleQueryDto  the role query dto
     *
     * @return 角色列表
     */
    @Override
    public List<UacRole> queryActionRoleList(RoleQueryDto roleQueryDto) {

        Long actionId = roleQueryDto.getActionId();

        Preconditions.checkArgument(actionId != null,
                cmnyMessageSource.getMessage("action.id.null", null));

        // 根据功能Id查询角色Id列表
        List<Long> roleIdList = uacRoleActionService.getCheckRoleList(actionId);

        if (PublicUtil.isEmpty(roleIdList)) {
            return uacRoleMapper.selectAll();
        } else {
            roleQueryDto.setRoleIds(StringUtils.join(roleIdList,","));

            return uacRoleMapper.queryActionRoleList(roleQueryDto);
        }
    }

    /**
     * 分配功能角色
     *
     * @param actionAssignRoleDto 分配功能角色对象
     *
     * @return 影响的行数
     */
    @Override
    public Integer assignActionRole(ActionAssignRoleDto actionAssignRoleDto) {

        // 判断功能Id
        Long actionId = actionAssignRoleDto.getActionId();
        Preconditions.checkArgument(actionId != null,
                cmnyMessageSource.getMessage("action.id.null", null));

        // 判断功能id是否存在
        UacAction uacAction = uacActionService.selectByKey(actionId);
        if (uacAction == null) {
            logger.error("找不到权限信息 actionId={}", actionId);
            throw new UacBizException(ErrorCodeEnum.UAC10014001, actionId);
        }

        List<Long> checkRoleList = Lists.newArrayList();
        List<Long> deleteRoleList = Lists.newArrayList();
        for (AssignRoleDto ard : actionAssignRoleDto.getAssignRoleDtoList()) {
            switch (ard.getCheck()) {
                case RoleConstant.CHECK_STATUS_SLT :
                    checkRoleList.add(ard.getRoleId());
                    break;
                case RoleConstant.CHECK_STATUS_RID :
                    deleteRoleList.add(ard.getRoleId());
                    break;
            }
        }

        int result = 0;
        if (PublicUtil.isNotEmpty(checkRoleList)) {
            // 批量添加
            result += uacRoleActionService.batchSaveActionAndRoleList(actionId, checkRoleList);
        }
        if (PublicUtil.isNotEmpty(deleteRoleList)) {

			// 判断是否含有初始化的角色功能
			int count = uacGroupRoleActionService.selectCountActionIdAndRoleIdList(actionId, deleteRoleList);
			if (count > 0) {
				throw new UacBizException(ErrorCodeEnum.UAC10014008);
			}

            // 批量删除
            result += uacRoleActionService.batchDeleteActionAndRoleList(actionId, deleteRoleList);
        }

        return result;
    }

	/**
	 * 通过用户ID查询角色详情
	 * @param userId
	 * @return
	 */
	@Override
	public List<RoleVo> selectByUserId(Long userId){
    	return uacRoleMapper.selectByUserId(userId);
	}
}
